package fantasma.estados;
import fabricas.FabricaEstados;
import fabricas.FabricaTiempo;
import fantasma.Fantasma;
import fantasma.tipos.FantasmaBuscadorTemperamental;
import fantasma.tipos.FantasmaPerezoso;
import interfaces.IEstado;
import interfaces.IManejadorDeTiempo;
import interfaces.IPacman;
import utilidades.Constantes;
import utilidades.ContadorDeCiclos;
import utilidades.Vector;

public class EstadoPresa implements IEstado {
	private Fantasma fantasma;
	private IManejadorDeTiempo manejadorTiempo;
	private ContadorDeCiclos contadorParaMoverse;

	private Vector direccionActual,ultimaDireccion;
	private Vector direccionAEvitar;	
	
	public EstadoPresa(Fantasma fantasma){
		this.fantasma = fantasma;
		this.manejadorTiempo = FabricaTiempo.crearManejadorDeTiempo(Constantes.TICKS_DE_PRESA_A_CAZADOR);
		this.contadorParaMoverse = FabricaTiempo.crearContadorDeCiclos(Constantes.CICLOS_PARA_MOVERSE);
		this.direccionActual = Constantes.IZQUIERDA;
		this.ultimaDireccion = Constantes.NULO;
		this.direccionAEvitar = Constantes.NULO;
	}
	
	public void transicionAMuerto(){
		fantasma.cambiarEstado(FabricaEstados.crearEstadoMuerto(fantasma));		
	}

	public void transicionAPresa(){
		fantasma.cambiarEstado(FabricaEstados.crearEstadoPresa(fantasma));
	}

	public void actualizarEstado(){
		manejadorTiempo.actualizarCantidadDeTicks();
		if(manejadorTiempo.llegoALaCantidadDeTicks()){
			fantasma.cambiarEstado(FabricaEstados.crearEstadoCazador(fantasma));
		}
	}

	@Override
	public void interactuarCon(IPacman pacman) {		
		fantasma.cambiarEstado(FabricaEstados.crearEstadoMuerto(fantasma));

		pacman.incrementarPuntaje(50);
		vista.Audio.reproducirSonido(Constantes.CLIP_PACMAN_COME_FANTASMA);	

		if(Constantes.MODO_DEBUG)
			System.out.printf("esPresa\n");
	}

	@Override
	public void moverComoBuscador(Fantasma fantasmaBuscador, IPacman pacman) {			
		if(seMueve()){
			Vector dir = obtenerDireccionContrariaSiEstaDentroDelRangoDeVision(pacman);

			boolean alejandoseDelPacman = !dir.esIgualA(Constantes.NULO);					
			if(!alejandoseDelPacman){
				dir = ultimaDireccion;
			}
			direccionAEvitar = dir.obtenerVectorContrario();
			direccionActual = fantasma.obtenerDireccionAlAzar(direccionAEvitar);
			
			ultimaDireccion = direccionActual;
			fantasma.moverseYAvisarSiHuboBifurcacion(direccionActual);
			direccionAEvitar = Constantes.NULO;
		}
	}	

	@Override
	public void moverComoBuscadorTemperamental(FantasmaBuscadorTemperamental fantasmaBuscadorTemperamental, IPacman pacman) {
		moverComoBuscador(fantasmaBuscadorTemperamental,pacman);
	}

	@Override
	public void moverComoZonzo(Fantasma fantasmaZonso, IPacman pacman) {
		moverComoBuscador(fantasmaZonso,pacman);
	}

	@Override
	public void moverComoPerezoso(FantasmaPerezoso fantasmaPerezoso, IPacman pacman) {
		moverComoBuscador(fantasmaPerezoso,pacman); 
	}
	
	
	private Vector obtenerDireccionContrariaSiEstaDentroDelRangoDeVision(IPacman pacman) {
		Vector dirPacman = fantasma.obtenerDireccionSiEstaDentroDelRangoDeVision(pacman);

		if (!dirPacman.esIgualA(Constantes.NULO)){
			return dirPacman.obtenerVectorContrario();
		}
		return Constantes.NULO;
	}	
	
	private boolean seMueve(){
		if(contadorParaMoverse.ocurreEnEsteCiclo(1)){
			return true;
		}
		return false;
	}
		
	@Override
	public String obtenerEstadoEnTexto() {
		return "Presa";
	}

	@Override
	public String obtenerDireccionEnTexto() {
		return direccionActual.convertirATexto();
	}

	@Override
	public Vector obtenerDireccion(){
		return direccionActual;
	}
	
	public boolean estaMuerto(){
		return false;
	}

	@Override
	public boolean esPresa() {
		return true;
	}

	@Override
	public Vector obtenerUltimaDireccion() {
		return ultimaDireccion;
	}
	@Override
	public int obtenerIra() {
		return 0;
	}
}